package de.gameduell.framework.queue  {
	
	import de.gameduell.framework.queue.ActionEvent;
	import de.gameduell.framework.queue.GDActionQueue;
	import de.gameduell.framework.queue.IGDAction;
	import de.gameduell.framework.threads.IThread;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.utils.getQualifiedClassName;	

	/**
	 * a long life component wants to block the -->> GLOBAL <<-- action queue.
	 * 
	 * compare:
	 * DelayAction: block for a fixed time.
	 * BlockingCallbackAction: block for unknown time, depending on a particular state.
	 * 
	 * @deprecated avoid singleton action queue, use thread pool manager and BlockingTimerThread instead - allow to run in different target queues 
	 * @author ftru
	 */
	public class BlockingCallbackAction extends EventDispatcher implements IGDAction {
		private var _blockingCallback:IThread;
		private var _timer:Timer;
		private var actionQueue:GDActionQueue;
		
		public function BlockingCallbackAction(blockingCallback:IThread, sleep:Number, invokeNow:Boolean = false) {
			_timer = new Timer(sleep, 0);
			_timer.addEventListener(TimerEvent.TIMER, checkForReleaseBlocking);	
			_blockingCallback = blockingCallback;
			actionQueue = GDActionQueue.getInstance();
			if(invokeNow){
				invoke();
			}		
		}
		
		private function checkForReleaseBlocking(event:TimerEvent):void {
			
			// relase the action queue if blockingCallback has finished its job
			if (!_blockingCallback.run()) {
				onTimerComplete(event);
			}
		}
			
		private function onTimerComplete(event:TimerEvent):void{
			_timer.reset();
			_timer.stop();
			dispatchEvent(new ActionEvent(ActionEvent.DONE));
		}
		
		public function compute():void {
			_timer.start();
		}
		
		public function invoke():void {
			actionQueue.add(this);
		}
		
		public function get description():String {
			return "BlockingCallbackAction blockingCallback = "+ getQualifiedClassName(_blockingCallback);
		}
	}
}
